__all__ = ['mktime_tz',
 'parsedate',
 'parsedate_tz',
 'quote']
import time
SPACE = ' '
EMPTYSTRING = ''
COMMASPACE = ', '
_monthnames = ['jan',
 'feb',
 'mar',
 'apr',
 'may',
 'jun',
 'jul',
 'aug',
 'sep',
 'oct',
 'nov',
 'dec',
 'january',
 'february',
 'march',
 'april',
 'may',
 'june',
 'july',
 'august',
 'september',
 'october',
 'november',
 'december']
_daynames = ['mon',
 'tue',
 'wed',
 'thu',
 'fri',
 'sat',
 'sun']
_timezones = {'UT': 0,
 'UTC': 0,
 'GMT': 0,
 'Z': 0,
 'AST': -400,
 'ADT': -300,
 'EST': -500,
 'EDT': -400,
 'CST': -600,
 'CDT': -500,
 'MST': -700,
 'MDT': -600,
 'PST': -800,
 'PDT': -700}

def parsedate_tz(data):
    data = data.split()
    if (data[0].endswith(',') or (data[0].lower() in _daynames)):
        del data[0]
    else:
        i = data[0].rfind(',')
        if (i >= 0):
            data[0] = data[0][(i + 1):]
    if (len(data) == 3):
        stuff = data[0].split('-')
        if (len(stuff) == 3):
            data = (stuff + data[1:])
    if (len(data) == 4):
        s = data[3]
        i = s.find('+')
        if (i > 0):
            data[3:] = [s[:i], s[(i + 1):]]
        else:
            data.append('')
    if (len(data) < 5):
        return 
    data = data[:5]
    (dd, mm, yy, tm, tz,) = data
    mm = mm.lower()
    if (mm not in _monthnames):
        (dd, mm,) = (mm, dd.lower())
        if (mm not in _monthnames):
            return 
        mm = (_monthnames.index(mm) + 1)
        if (mm > 12):
            mm -= 12
        if (dd[-1] == ','):
            dd = dd[:-1]
        i = yy.find(':')
        if (i > 0):
            (yy, tm,) = (tm, yy)
        if (yy[-1] == ','):
            yy = yy[:-1]
        if not yy[0].isdigit():
            (yy, tz,) = (tz, yy)
        if (tm[-1] == ','):
            tm = tm[:-1]
        tm = tm.split(':')
        if (len(tm) == 2):
            (thh, tmm,) = tm
            tss = '0'
        elif (len(tm) == 3):
            (thh, tmm, tss,) = tm
        else:
            return 
        try:
            yy = int(yy)
            dd = int(dd)
            thh = int(thh)
            tmm = int(tmm)
            tss = int(tss)
        except ValueError:
            return 
        else:
            tzoffset = None
            tz = tz.upper()
            if (tz in _timezones):
                tzoffset = _timezones[tz]
            else:
                try:
                    tzoffset = int(tz)
                except ValueError:
                    pass
        if tzoffset:
            if (tzoffset < 0):
                tzsign = -1
                tzoffset = -tzoffset
            else:
                tzsign = 1
            tzoffset = (tzsign * (((tzoffset // 100) * 3600) + ((tzoffset % 100) * 60)))
        return (yy,
         mm,
         dd,
         thh,
         tmm,
         tss,
         0,
         1,
         -1,
         tzoffset)



def parsedate(data):
    t = parsedate_tz(data)
    if isinstance(t, tuple):
        return t[:9]
    else:
        return t



def mktime_tz(data):
    if (data[9] is None):
        return time.mktime((data[:8] + (-1,)))
    else:
        t = time.mktime((data[:8] + (0,)))
        return ((t - data[9]) - time.timezone)



def quote(str):
    return str.replace('\\', '\\\\').replace('"', '\\"')



class AddrlistClass:

    def __init__(self, field):
        self.specials = '()<>@,:;."[]'
        self.pos = 0
        self.LWS = ' \t'
        self.CR = '\r\n'
        self.FWS = (self.LWS + self.CR)
        self.atomends = ((self.specials + self.LWS) + self.CR)
        self.phraseends = self.atomends.replace('.', '')
        self.field = field
        self.commentlist = []



    def gotonext(self):
        while ((self.pos < len(self.field)) and
               (self.field[self.pos] in (self.LWS + '\n\r'))):
            self.pos += 1
            continue
            if (self.field[self.pos] == '('):
                self.commentlist.append(self.getcomment())
            else:
                break




    def getaddrlist(self):
        result = []
        while (self.pos < len(self.field)):
            ad = self.getaddress()
            if ad:
                result += ad
            else:
                result.append(('', ''))

        return result



    def getaddress(self):
        self.commentlist = []
        self.gotonext()
        oldpos = self.pos
        oldcl = self.commentlist
        plist = self.getphraselist()
        self.gotonext()
        returnlist = []
        if (self.pos >= len(self.field)):
            if plist:
                returnlist = [(SPACE.join(self.commentlist), plist[0])]
        elif (self.field[self.pos] in '.@'):
            self.pos = oldpos
            self.commentlist = oldcl
            addrspec = self.getaddrspec()
            returnlist = [(SPACE.join(self.commentlist), addrspec)]
        elif (self.field[self.pos] == ':'):
            returnlist = []
            fieldlen = len(self.field)
            self.pos += 1
            while (self.pos < len(self.field)):
                self.gotonext()
                if ((self.pos < fieldlen) and (self.field[self.pos] == ';')):
                    self.pos += 1
                    break
                returnlist = (returnlist + self.getaddress())

        elif (self.field[self.pos] == '<'):
            routeaddr = self.getrouteaddr()
            if self.commentlist:
                returnlist = [((((SPACE.join(plist) + ' (') + ' '.join(self.commentlist)) + ')'), routeaddr)]
            else:
                returnlist = [(SPACE.join(plist), routeaddr)]
        elif plist:
            returnlist = [(SPACE.join(self.commentlist), plist[0])]
        elif (self.field[self.pos] in self.specials):
            self.pos += 1
        self.gotonext()
        if ((self.pos < len(self.field)) and (self.field[self.pos] == ',')):
            self.pos += 1
        return returnlist



    def getrouteaddr(self):
        if (self.field[self.pos] != '<'):
            return 
        else:
            expectroute = False
            self.pos += 1
            self.gotonext()
            adlist = ''
            while (self.pos < len(self.field)):
                if expectroute:
                    self.getdomain()
                    expectroute = False
                elif (self.field[self.pos] == '>'):
                    self.pos += 1
                    break
                elif (self.field[self.pos] == '@'):
                    self.pos += 1
                    expectroute = True
                elif (self.field[self.pos] == ':'):
                    self.pos += 1
                else:
                    adlist = self.getaddrspec()
                    self.pos += 1
                    break
                self.gotonext()

            return adlist



    def getaddrspec(self):
        aslist = []
        self.gotonext()
        while (self.pos < len(self.field)):
            if (self.field[self.pos] == '.'):
                aslist.append('.')
                self.pos += 1
            elif (self.field[self.pos] == '"'):
                aslist.append(('"%s"' % self.getquote()))
            elif (self.field[self.pos] in self.atomends):
                break
            else:
                aslist.append(self.getatom())
            self.gotonext()

        if ((self.pos >= len(self.field)) or (self.field[self.pos] != '@')):
            return EMPTYSTRING.join(aslist)
        else:
            aslist.append('@')
            self.pos += 1
            self.gotonext()
            return (EMPTYSTRING.join(aslist) + self.getdomain())



    def getdomain(self):
        sdlist = []
        while (self.pos < len(self.field)):
            if (self.field[self.pos] in self.LWS):
                self.pos += 1
            elif (self.field[self.pos] == '('):
                self.commentlist.append(self.getcomment())
            elif (self.field[self.pos] == '['):
                sdlist.append(self.getdomainliteral())
            elif (self.field[self.pos] == '.'):
                self.pos += 1
                sdlist.append('.')
            elif (self.field[self.pos] in self.atomends):
                break
            else:
                sdlist.append(self.getatom())

        return EMPTYSTRING.join(sdlist)



    def getdelimited(self, beginchar, endchars, allowcomments = True):
        if (self.field[self.pos] != beginchar):
            return ''
        else:
            slist = ['']
            quote = False
            self.pos += 1
            while (self.pos < len(self.field)):
                if quote:
                    slist.append(self.field[self.pos])
                    quote = False
                elif (self.field[self.pos] in endchars):
                    self.pos += 1
                    break
                elif (allowcomments and (self.field[self.pos] == '(')):
                    slist.append(self.getcomment())
                    continue
                elif (self.field[self.pos] == '\\'):
                    quote = True
                else:
                    slist.append(self.field[self.pos])
                self.pos += 1

            return EMPTYSTRING.join(slist)



    def getquote(self):
        return self.getdelimited('"', '"\r', False)



    def getcomment(self):
        return self.getdelimited('(', ')\r', True)



    def getdomainliteral(self):
        return ('[%s]' % self.getdelimited('[', ']\r', False))



    def getatom(self, atomends = None):
        atomlist = ['']
        if (atomends is None):
            atomends = self.atomends
        while (self.pos < len(self.field)):
            if (self.field[self.pos] in atomends):
                break
            else:
                atomlist.append(self.field[self.pos])
            self.pos += 1

        return EMPTYSTRING.join(atomlist)



    def getphraselist(self):
        plist = []
        while ((self.pos < len(self.field)) and
               (self.field[self.pos] in self.FWS)):
            self.pos += 1
            continue
            if (self.field[self.pos] == '"'):
                plist.append(self.getquote())
            elif (self.field[self.pos] == '('):
                self.commentlist.append(self.getcomment())
            elif (self.field[self.pos] in self.phraseends):
                break
            else:
                plist.append(self.getatom(self.phraseends))

        return plist




class AddressList(AddrlistClass):

    def __init__(self, field):
        AddrlistClass.__init__(self, field)
        if field:
            self.addresslist = self.getaddrlist()
        else:
            self.addresslist = []



    def __len__(self):
        return len(self.addresslist)



    def __add__(self, other):
        newaddr = AddressList(None)
        newaddr.addresslist = self.addresslist[:]
        for x in other.addresslist:
            if (x not in self.addresslist):
                newaddr.addresslist.append(x)

        return newaddr



    def __iadd__(self, other):
        for x in other.addresslist:
            if (x not in self.addresslist):
                self.addresslist.append(x)

        return self



    def __sub__(self, other):
        newaddr = AddressList(None)
        for x in self.addresslist:
            if (x not in other.addresslist):
                newaddr.addresslist.append(x)

        return newaddr



    def __isub__(self, other):
        for x in other.addresslist:
            if (x in self.addresslist):
                self.addresslist.remove(x)

        return self



    def __getitem__(self, index):
        return self.addresslist[index]




